<html>
 <head>
  <meta charset="UTF-8">
 </head>
 <body>
  <h1 data-lake-id="G8h3i" id="G8h3i"><span data-lake-id="u88feb540" id="u88feb540">典型回答</span></h1>
  <p data-lake-id="u5fa6b73a" id="u5fa6b73a"><br></p>
  <p data-lake-id="uffcb3b1f" id="uffcb3b1f"><span data-lake-id="u640411bf" id="u640411bf">不是的，主键是可以自己选择的，我们可以选择任意一种数据类型作为主键。</span></p>
  <p data-lake-id="u6f5900bc" id="u6f5900bc"><span data-lake-id="u2009e085" id="u2009e085">​</span><br></p>
  <p data-lake-id="uc610eca7" id="uc610eca7"><span data-lake-id="u2fd085fa" id="u2fd085fa">但是一般都是单独创建一个自增字段作为主键，主要能带来以下几个好处：</span></p>
  <p data-lake-id="ufc4b47a3" id="ufc4b47a3"><span data-lake-id="uf65aa996" id="uf65aa996">​</span><br></p>
  <ol list="u422db1a8">
   <li fid="ud0ab7585" data-lake-id="ucdaa823b" id="ucdaa823b"><span data-lake-id="u3369bbf6" id="u3369bbf6">索引大小更小：使用自增主键可以确保主键的递增性，使得新插入的数据都会在索引的末尾处，减少了数据页的分裂和页分裂导致的IO操作，使得索引大小更小，查询速度更快。</span></li>
   <li fid="ud0ab7585" data-lake-id="u8151ba1f" id="u8151ba1f"><span data-lake-id="u1037ce46" id="u1037ce46">索引顺序和插入顺序相同：使用自增主键可以保证索引顺序和插入顺序相同，减少了插入新数据时索引的重新排序，提高了插入速度。</span></li>
   <li fid="ud0ab7585" data-lake-id="u61ec80ad" id="u61ec80ad"><span data-lake-id="ubc9cf76a" id="ubc9cf76a">安全性：使用自增主键可以避免主键重复的情况，确保数据完整性和唯一性。</span></li>
   <li fid="ud0ab7585" data-lake-id="u05bd7719" id="u05bd7719"><span data-lake-id="uaaef31a6" id="uaaef31a6">减少页分裂（合并）及内存碎片。</span></li>
  </ol>
  <p data-lake-id="uc90cd638" id="uc90cd638"><span data-lake-id="u62e820c4" id="u62e820c4">​</span><br></p>
  <p data-lake-id="u7abe78e8" id="u7abe78e8"><span data-lake-id="u24445aeb" id="u24445aeb">​</span><br></p>
  <p data-lake-id="ubb540884" id="ubb540884"><span data-lake-id="u94a63cfe" id="u94a63cfe">另外，即使我们用了自增字段作为主键，最后体现在数据库上，字段也可能不是连续自增的，比如做了某一次插入失败但是主键ID被占用了，比如数据做了删除，比如做了回滚、比如做了数据订正等等。</span></p>
  <h1 data-lake-id="aBs7V" id="aBs7V"><span data-lake-id="u9c3ffcc0" id="u9c3ffcc0">扩展知识</span></h1>
  <p data-lake-id="uacfe93ac" id="uacfe93ac"><br></p>
  <h2 data-lake-id="gwayW" id="gwayW"><span data-lake-id="u557b9ccb" id="u557b9ccb">如果没有定义主键怎么办？</span></h2>
  <p data-lake-id="uf1793f53" id="uf1793f53"><br></p>
  <p data-lake-id="u3bf5e913" id="u3bf5e913"><span data-lake-id="u24ec7cbe" id="u24ec7cbe">如果我们在一张表中没有定义主键，那么，MySQL会默认选择一个唯一的非空索引作为聚簇索引。</span></p>
  <p data-lake-id="u4055195d" id="u4055195d"><span data-lake-id="u8413959c" id="u8413959c">​</span><br></p>
  <p data-lake-id="udafdb7d6" id="udafdb7d6"><span data-lake-id="ue9d0beff" id="ue9d0beff">如果没有适合的非空唯一索引，则会创建一个隐藏的主键（row_id）作为聚簇索引。</span></p>
  <p data-lake-id="u175d9bdd" id="u175d9bdd"><span data-lake-id="u95566c3e" id="u95566c3e">​</span><br></p>
  <p data-lake-id="ue1451e6c" id="ue1451e6c"><span data-lake-id="u63f8384f" id="u63f8384f">这个隐藏的主键包含一个自增列和一个6字节的定长记录指针，对用户透明，即用户无法看到或修改这个列，但可以通过使用该列来进行排序或连接操作。</span></p>
 </body>
</html>